﻿namespace FitnessTracker.Packet
{
    using System;
    using System.Linq;

    using FitnessTracker.Entities;

    public static class HxMPacketIntegrityValidator
    {
        private static readonly FitnessTrackerEntities FitnessTrackerEntities = new FitnessTrackerEntities();

        public static bool IsCRCValid(byte[] buffer)
        {
            var currentChecksum = (byte)0;

            for (var index = HxMPacketStructure.FirmwareIDOffset; index < HxMPacketStructure.CRCOffset; index++)
            {
                currentChecksum = ChecksumPushByte(currentChecksum, buffer.ElementAt(index));
            }

           if (currentChecksum != buffer.ElementAt(HxMPacketStructure.CRCOffset))
           {
               LogFaultyPacket(buffer, currentChecksum);
               return false;
           }

            return true;
        }

        private static byte ChecksumPushByte(byte currentChecksum, byte newByte)
        {
            currentChecksum ^= newByte;
            for (var index = 0; index < 8; ++index)
            {
                if ((currentChecksum & 1) == 1)
                {
                    currentChecksum = (byte)(currentChecksum >> 1 ^ 140);
                }
                else
                {
                    currentChecksum >>= 1;
                }
            }

            return currentChecksum;
        }

        private static void LogFaultyPacket(byte[] bufferData, byte expectedCheckSum)
        {
            var packetFaultsLog = new PacketFaultsLog
            {
                timeStamp = DateTime.Now,
                description = "CRC Validation Failed. Actual CRC was " + 
                               bufferData.ElementAt(HxMPacketStructure.CRCOffset) + "." +
                               "Expected CRS was " + expectedCheckSum,
                packet = bufferData
            };
            FitnessTrackerEntities.PacketFaultsLogs.Add(packetFaultsLog);
            FitnessTrackerEntities.SaveChanges();
        }
    }
}
